package test;

import org.bhf.service.AbstractComponent;
import org.bhf.service.ComponentInfo;
import org.bhf.service.EventQueue;
import org.bhf.service.Service;
import org.bhf.service.ServiceMethod;
import org.bhf.service.view.ComponentProcessView;

@Service( name = "calc", view = ComponentProcessView.class )
@ComponentInfo( eventGroup = CalculatorComponent.CalculatorEvents.class )
public class CalculatorComponent extends AbstractComponent
{
    private double              currentValue;
    private CalculatorEvents    events = EventQueue.getNewQueue( CalculatorComponent.CalculatorEvents.class );

    public double getCurrentValue()
    {
        return currentValue;
    }

    public void setCurrentValue( final double currentValue )
    {
        this.currentValue = currentValue;
    }

    @ServiceMethod
    public void     add( final double x )
    {
        currentValue += x;
        events.update();
    }

    @ServiceMethod
    public void     sub( final double x )
    {
        currentValue -= x;
        events.update();
    }

    @ServiceMethod
    public void     div( final double x )
    {
        currentValue /= x;
        events.update();
    }

    @ServiceMethod
    public void     mul( final double x )
    {
        currentValue *= x;
        events.update();
    }

    @ServiceMethod
    public double   currentValue()
    {
        notChanged();
        return currentValue;
    }

    @ServiceMethod
    public void     echoWithEventString( final String x )
    {
        events.echo( x );
    }

    @ServiceMethod
    public void     echoWithEventComplex( final ComplexNumber x )
    {
        events.echo( x );
    }

    @ServiceMethod
    public void     echoWithEventComplexParts( final ComplexNumber x )
    {
        events.echo( x.real,  x.imaginary);
    }

    interface CalculatorEvents
    {
        void    update();
        void    echo( final String x );
        void    echo( final ComplexNumber x );
        void    echo( final float x, final float y );
    }

    public static class ComplexNumber
    {
        private float   real;
        private float   imaginary;

        public ComplexNumber() { }

        public ComplexNumber( final float real, final float imaginary )
        {
            this.real = real;
            this.imaginary = imaginary;
        }

        public float getReal()
        {
            return real;
        }

        public void setReal( final float real )
        {
            this.real = real;
        }

        public float getImaginary()
        {
            return imaginary;
        }

        public void setImaginary( final float imaginary )
        {
            this.imaginary = imaginary;
        }
    }
}
